package com.dsg.controller.apply;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dsg.common.constants.MessageConstants;
import com.dsg.common.dto.AjaxResult;
import com.dsg.common.util.BeanKit;
import com.dsg.common.util.SingletonLoginUtils;
import com.dsg.common.util.UUIDGenerator;
import com.dsg.common.util.toolbox.CollectionUtil;
import com.dsg.common.util.toolbox.DateUtil;
import com.dsg.common.util.toolbox.StringUtil;
import com.dsg.controller.base.BaseController;
import com.dsg.entity.apply.*;
import com.dsg.entity.dto.*;
import com.dsg.service.apply.*;
import com.dsg.service.oil.IDsgOilDataDetailService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 個人申請資料 前端控制器
 * </p>
 *
 * @author system
 * @since 2020-07-04
 */
@RestController
@RequestMapping("/apply/dsgApplyCus")
@Slf4j
@Api(description = "個人申請資料")
public class DsgApplyCusController extends BaseController {
    
    @Autowired
    IDsgApplyCusService service;
    @Autowired
    IDsgApplyContactService contactService;
    @Autowired
    IDsgApplyDiscountService discountService;
    @Autowired
    IDsgApplyCusService cusService;
    @Autowired
    IDsgApplyComService comService;
    @Autowired
    IDsgApplyCardService cardService;
    @Autowired
    IDsgApplyPayService payService;
    @Autowired
    IDsgOilDataDetailService oilDataDetailService;
    @Autowired
    IDsgApplyCarService carService;
    @Autowired
    IDsgApplyBillService billService;

    @PutMapping(value = "/update")
    @ApiOperation("更新")
    public AjaxResult update(@RequestBody DsgApplyCus cus) {
        boolean flag = service.updateById(cus);
        if (flag) {
            return json(MessageConstants.SSO_STATUS_SUCCESS, cus);
        } else {
            return result(MessageConstants.SSO_STATUS_FAIL);
        }
    }

//    @PostMapping(value = "/add")
//    @ApiOperation("新增")
//    @Transactional(rollbackFor = Exception.class)
//    public AjaxResult add(@RequestBody DsgApplyCus applyCus) {
//        applyCus.setOid(UUIDGenerator.getUUID());
//        service.save(applyCus);
//        List<DsgApplyContact> contactList = applyCus.getContactList();
//        if (CollectionUtil.isNotEmpty(contactList)) {
//            for (DsgApplyContact contact:
//                 contactList) {
//                contact.setOid(UUIDGenerator.getUUID());
//                contact.setPid(applyCus.getOid());
//            }
//            contactService.saveBatch(contactList);
//        }
//
//        return json(MessageConstants.SSO_STATUS_SUCCESS, applyCus);
//    }

    @PutMapping(value = "/saveOrUpdate")
    @ApiOperation("新增或更新")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult saveOrUpdate(@RequestBody DsgApplyCus applyCus) throws Exception {
        if (StringUtil.isEmpty(applyCus.getMainNo()) || StringUtil.isEmpty(applyCus.getAppNo())) {
            return fail("mainNo和appNo不能為空");
        }

        if (StringUtil.isEmpty(applyCus.getOid())) {
            applyCus.setOid(UUIDGenerator.getUUID());
            String cusNo = DateUtil.format(new Date(), "yyyyMMddHHmmss");
            applyCus.setCusNo(cusNo);

            QueryWrapper wrapper1 = new QueryWrapper();
            wrapper1.eq("APP_NO", applyCus.getAppNo());
            DsgApplyBill bill = billService.getOne(wrapper1);
            bill.setCusId(applyCus.getOid());
            billService.updateById(bill);

//            if (DsgApplyBill.APP_TYPE_1 == bill.getAppType() || DsgApplyBill.APP_TYPE_22 == bill.getAppType()) {
                if (DsgApplyBill.APP_TYPE_1 == bill.getAppType()) {
                    LambdaUpdateWrapper<DsgApplyPay> updateWrapper = new LambdaUpdateWrapper();
                    updateWrapper.eq(DsgApplyPay::getAppNo, applyCus.getAppNo());
                    DsgApplyPay pay = new DsgApplyPay();
                    pay.setCusNo(applyCus.getCusNo());
                    payService.update(pay, updateWrapper);
                }

                LambdaUpdateWrapper<DsgApplyCar> carUpdate = new LambdaUpdateWrapper<>();
                carUpdate.eq(DsgApplyCar::getAppNo, applyCus.getAppNo());
                DsgApplyCar car = new DsgApplyCar();
                car.setCusNo(applyCus.getCusNo());
                carService.update(car, carUpdate);
//            }

            LambdaUpdateWrapper<DsgApplyCard> cardUpdate = new LambdaUpdateWrapper();
            cardUpdate.eq(DsgApplyCard::getAppNo, bill.getAppNo());
            DsgApplyCard card = new DsgApplyCard();
            card.setCusNo(cusNo);
            cardService.update(card, cardUpdate);
        }
        service.saveOrUpdate(applyCus);
        saveContact(applyCus.getOid(), applyCus.getContactList());
        return json(MessageConstants.SSO_STATUS_SUCCESS, applyCus);
    }

    @DeleteMapping(value = "/delete")
    @ApiOperation("删除")
    public AjaxResult delete(String id) {
        Boolean flag = service.removeById(id);
        if (flag) {
            return result(MessageConstants.SSO_STATUS_SUCCESS);
        } else {
            return result(MessageConstants.SSO_STATUS_FAIL);
        }
    }

    @GetMapping(value = "/{mainNo}/getByBill")
    @ApiOperation("查询单条数据")
    public AjaxResult getByBill(@PathVariable String mainNo) {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("MAIN_NO", mainNo);
        DsgApplyCus applyCus = service.getOne(wrapper);
        return json(MessageConstants.SSO_STATUS_SUCCESS, applyCus);
    }

    @PutMapping(value = "/edit")
    @ApiOperation("重新编辑")
    public AjaxResult edit(@RequestBody DsgApplyCus applyCus) {
        applyCus.setVerify(DsgApplyCus.VERIFY_NO);
        service.updateById(applyCus);
        return json(MessageConstants.SSO_STATUS_SUCCESS, applyCus);
    }

    @PutMapping(value = "/verify")
    @ApiOperation("完成核对")
    public AjaxResult verify(@RequestBody DsgApplyCus applyCus) {
        applyCus.setVerify(DsgApplyCus.VERIFY_YES);
        service.updateById(applyCus);
        return json(MessageConstants.SSO_STATUS_SUCCESS, applyCus);
    }

    @GetMapping(value = "/selectByKeepType")
    @ApiOperation("客戶資料搜尋-記賬咭/現金咭")
    public AjaxResult selectByKeepType(CusSearchDto dto) {
        dto.setEntCode(getEntCode());
        return json(MessageConstants.SSO_STATUS_SUCCESS, service.selectByKeepType(dto));
    }

    @GetMapping(value = "/selectApplyCus")
    @ApiOperation("客戶資料搜尋-申請中客戶")
    public AjaxResult selectApplyCus(CusSearchDto dto) {
        dto.setEntCode(getEntCode());
        return json(MessageConstants.SSO_STATUS_SUCCESS, service.selectApplyCus(dto));
    }

    @GetMapping(value = "/selectCus")
    @ApiOperation("客戶資料-客戶概覽-客戶資料")
    @ApiResponses({
            @ApiResponse(response = CusSumDto.class, code = 1, message = "ok")
    })
    public AjaxResult selectCus(String cusNo) {
        return json(MessageConstants.SSO_STATUS_SUCCESS, service.selectCus(cusNo));
    }

    @GetMapping(value = "/selectContact")
    @ApiOperation("客戶資料-客戶概覽-通訊資料")
    @ApiResponses({
            @ApiResponse(response = ContactDto.class, code = 1, message = "ok")
    })
    public AjaxResult selectContact(String cusNo) {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("CUS_NO", cusNo);
        wrapper.orderByDesc("CREATE_TIME");
        DsgApplyCus cus = cusService.getOne(wrapper, false);
        ContactDto dto = new ContactDto();
        String pid;
        if (cus != null) {
            pid = cus.getOid();
            dto.setMobilePhone(cus.getMobilePhone());
            dto.setTelPhone(cus.getTelPhone());
        } else {
            wrapper = new QueryWrapper();
            wrapper.eq("COM_NO", cusNo);
            DsgApplyCom com = comService.getOne(wrapper);
            dto.setComTel(com.getComTel());
            pid = com.getOid();
        }
        wrapper = new QueryWrapper();
        wrapper.eq("PID", pid);
        List<DsgApplyContact> contactList = contactService.list(wrapper);
        dto.setContactList(contactList);

        return json(MessageConstants.SSO_STATUS_SUCCESS, dto);
    }

    @GetMapping(value = "/selectCusCard")
    @ApiOperation("客戶資料-客戶概覽-油咭資料及狀況")
    @ApiResponses(
            @ApiResponse(response = CusCardDto.class, code = 0, message = "ok")
    )
    public AjaxResult selectCusCard(String cusNo) {
        String ownsId = service.getOwnsIdByCusNo(cusNo);
        CusCardSearchDto dto = new CusCardSearchDto();
        dto.setOwnsId(ownsId);
        dto.setEntCode(getEntCode());
        return json(MessageConstants.SSO_STATUS_SUCCESS, cardService.selectCusCard(dto));
    }

    @GetMapping(value = "/selectPay")
    @ApiOperation("客戶資料-客戶概覽-繳款資料")
    @ApiResponses(
            @ApiResponse(response = CusPayDto.class, code = 0, message = "ok")
    )
    public AjaxResult selectPay(String cusNo) {
        String ownsId = service.getOwnsIdByCusNo(cusNo);
        return json(MessageConstants.SSO_STATUS_SUCCESS, payService.selectPay(ownsId));
    }

    @GetMapping(value = "/selectRecent")
    @ApiOperation("客戶資料-客戶概覽-最近入油")
    @ApiResponses(
            @ApiResponse(response = RecentOilDto.class, code = 0, message = "ok")
    )
    public AjaxResult selectRecent(String cusNo, String carNo) {
        String ownsId = service.getOwnsIdByCusNo(cusNo);
        return json(MessageConstants.SSO_STATUS_SUCCESS, oilDataDetailService.selectRecent(ownsId, carNo));
    }

    @GetMapping(value = "/carNoList")
    @ApiOperation("客戶資料-客戶概覽-最近入油-車牌號下拉列表")
    public AjaxResult carNoList(String cusNo) {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.select("DISTINCT CAR_NO");
        wrapper.eq("CUS_NO", cusNo);
        wrapper.isNotNull("CAR_NO");
        List<DsgApplyCar> carList = carService.list(wrapper);
        List<String> carNoList = carList.stream().map(DsgApplyCar::getCarNo).collect(Collectors.toList());
        return json(MessageConstants.SSO_STATUS_SUCCESS, carNoList);
    }

    @GetMapping(value = "/selectKeepCard")
    @ApiOperation("客戶資料-記賬卡管理(折扣咭管理)")
    @ApiResponses(
            @ApiResponse(response = CusCardDto.class, code = 0, message = "ok")
    )
    public AjaxResult selectKeepCard(CusCardSearchDto dto) {
        String ownsId = service.getOwnsIdByCusNo(dto.getCusNo());
        dto.setOwnsId(ownsId);
        dto.setCardClassify(DsgApplyCard.CARD_CLASSIFY_KEEP);
        dto.setEntCode(getEntCode());
        return json(MessageConstants.SSO_STATUS_SUCCESS, cardService.selectCusCard(dto));
    }

    @GetMapping(value = "/selectCashCard")
    @ApiOperation("客戶資料-現金卡管理")
    @ApiResponses(
            @ApiResponse(response = CusCardDto.class, code = 0, message = "ok")
    )
    public AjaxResult selectCashCard(CusCardSearchDto dto) {
        String ownsId = service.getOwnsIdByCusNo(dto.getCusNo());
        dto.setOwnsId(ownsId);
        dto.setCardClassify(DsgApplyCard.CARD_CLASSIFY_CASH);
        dto.setEntCode(getEntCode());
        return json(MessageConstants.SSO_STATUS_SUCCESS, cardService.selectCusCard(dto));
    }

    @GetMapping(value = "/selectCusPay")
    @ApiOperation("客戶資料-繳款資料-繳款資料記錄")
    @ApiResponses(
            @ApiResponse(response = CusPaymentDto.class, code = 0, message = "ok")
    )
    public AjaxResult selectCusPay(String cusNo, String carNo, String payAccountNo) {
        String ownsId = service.getOwnsIdByCusNo(cusNo);
        return json(MessageConstants.SSO_STATUS_SUCCESS, payService.selectCusPay(ownsId, false, carNo, payAccountNo));
    }

    @GetMapping(value = "/selectOnProcessPay")
    @ApiOperation("客戶資料-繳款資料-處理中的繳款資料")
    @ApiResponses(
            @ApiResponse(response = CusPaymentDto.class, code = 0, message = "ok")
    )
    public AjaxResult selectOnProcessPay(String cusNo, String carNo, String payAccountNo) {
        String ownsId = service.getOwnsIdByCusNo(cusNo);
        return json(MessageConstants.SSO_STATUS_SUCCESS, payService.selectCusPay(ownsId, true, carNo, payAccountNo));
    }

    @GetMapping(value = "/getCusInfo")
    @ApiOperation("客戶資料-客戶資料-查询")
    @ApiResponses(
            @ApiResponse(response = CusInfoDto.class, code = 0, message = "ok")
    )
    public AjaxResult getCusInfo(String cusNo) {
        String ownsId = null;
        CusInfoDto dto = new CusInfoDto();
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("CUS_NO", cusNo);
        DsgApplyCus cus = cusService.getOne(wrapper);
        if (cus != null) {
            dto.setCus(cus);
            ownsId = cus.getOid();
        } else {
            wrapper = new QueryWrapper();
            wrapper.eq("COM_NO", cusNo);
            DsgApplyCom com = comService.getOne(wrapper);
            if (com != null) {
                dto.setCom(com);
                ownsId = com.getOid();
            }
        }
        wrapper = new QueryWrapper();
        wrapper.eq("CUS_NO", cusNo);
        List<DsgApplyDiscount> discountList = discountService.list(wrapper);
        dto.setDiscountList(discountList);
        wrapper = new QueryWrapper();
        wrapper.eq("PID", ownsId);
        List<DsgApplyContact> contactList = contactService.list(wrapper);
        dto.setContactList(contactList);

        for (DsgApplyContact contact:contactList) {
            if (contact.getContactType().intValue() == DsgApplyContact.CONTACT_TYPE_ADDRESS.intValue()) {
                wrapper = new QueryWrapper();
                wrapper.eq("COMM_ID", contact.getOid());
                List<DsgApplyCar> carList = carService.list(wrapper);
                contact.setCarList(carList);
            }
        }

        return json(MessageConstants.SSO_STATUS_SUCCESS, dto);
    }

    @PutMapping(value = "updateCusInfo")
    @ApiOperation("客戶資料-客戶資料-保存")
    @ApiResponses(
            @ApiResponse(response = CusInfoDto.class, code = 0, message = "ok")
    )
    public AjaxResult updateCusInfo(CusInfoDto dto) throws Exception {
        String ownsId = null;
        String cusNo = null;
        DsgApplyCus cus = dto.getCus();
        if (cus != null) {
            cusService.updateById(cus);
            ownsId = cus.getOid();
            cusNo = cus.getCusNo();
        }

        DsgApplyCom com = dto.getCom();
        if (com != null) {
            comService.updateById(com);
            ownsId = com.getOid();
            cusNo = com.getComNo();
        }

        List<DsgApplyDiscount> discountList = dto.getDiscountList();
        List<DsgApplyContact> contactList = dto.getContactList();
        saveContact(ownsId, contactList);
        discountService.saveDiscount(cusNo, discountList);
        return success(dto);
    }

    private void saveContact(String ownsId, List<DsgApplyContact> contactList) throws Exception {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.select("OID");
        wrapper.eq("PID", ownsId);
        List<DsgApplyContact> preContactList = contactService.list(wrapper);
        List<String> preOids = null;
        List<String> oids = null;
        if (CollectionUtil.isNotEmpty(preContactList)) {
            preOids = preContactList.stream().map(DsgApplyContact::getOid).collect(Collectors.toList());
        }

        if (CollectionUtil.isNotEmpty(contactList)) {
            oids = contactList.stream().map(DsgApplyContact::getOid).collect(Collectors.toList());
            for (DsgApplyContact contact:
                    contactList) {
                if (StringUtil.isEmpty(contact.getOid())) {
                    contact.setOid(UUIDGenerator.getUUID());
                    contact.setPid(ownsId);
                    if (DsgApplyContact.CONTACT_TYPE_ADDRESS == contact.getContactType()) {
                        contact.setRelationType(null);
                    }
                }
            }
            contactService.saveOrUpdateBatch(contactList);
        }

        if (CollectionUtil.isNotEmpty(preOids)) {
            if (CollectionUtil.isNotEmpty(oids)) {
                preOids.removeAll(oids);
            }
            if (CollectionUtil.isNotEmpty(preOids)) {
                contactService.removeByIds(preOids);
            }
        }
    }

    @GetMapping(value = "/selectApplyList")
    @ApiOperation("客服中心-申請列表")
    @ApiResponses(
            @ApiResponse(response = ApplyList.class, code = 0, message = "ok")
    )
    public AjaxResult selectApplyList(Integer appType, String appNo, Integer appStatus, String carNo, String cusNo, Integer keepType) {
        Page page = getPage();
        page = service.applyList(page, appType, appNo, appStatus, carNo, cusNo, getEntCode(), keepType);
        return json(MessageConstants.SSO_STATUS_SUCCESS, page.getRecords(), (int) page.getTotal());
    }

    @GetMapping(value = "/cusAndComNoList")
    @ApiOperation("客戶和公司編號下拉")
    public AjaxResult cusAndComNoList() {
        List<DsgApplyCus> dsgApplyCusList = service.getCusAndComNoList(SingletonLoginUtils.getSystemEntCode(), 1);
        return json(MessageConstants.SSO_STATUS_SUCCESS, dsgApplyCusList);
    }

    @GetMapping(value = "/cusAndComCardNoList")
    @ApiOperation("客戶油咭編號下拉")
    public AjaxResult cusAndComCardNoList(String cusNo) {
        List<DsgApplyCard> dsgApplyCardList = service.getCusAndComCardNoList(SingletonLoginUtils.getSystemEntCode(), cusNo);
        return json(MessageConstants.SSO_STATUS_SUCCESS, dsgApplyCardList);
    }

    @GetMapping(value = "/getCusInfoByIdNo")
    @ApiOperation("查找已存在的客戶資料")
    public AjaxResult getCusInfoByIdNo(@RequestParam String idNo, @RequestParam Integer ownsType) {
        if (StringUtil.isEmpty(idNo))
            return fail("idNo不能為空");
        Object cusInfo = null;
        String cusId = null;
        QueryWrapper wrapper = new QueryWrapper();
        String appNo = DateUtil.format(new Date(), "yyyyMMddHHmmss");
        String oid = UUIDGenerator.getUUID();
        if (ownsType == DsgApplyBill.OWNS_TYPE_CUS) {
            wrapper.eq("ID_NO", idNo);
            wrapper.eq("CUS_STATUS", DsgApplyCus.CUS_STATUS_1);
            DsgApplyCus cus = service.getOne(wrapper, false);
            if (cus != null) {
                cus.setAppNo(appNo);
                cus.setContactList(getContactList(cusId, oid));
                cus.setOid(UUIDGenerator.getUUID());
                BeanKit.resetCommonField(cus);
                cus.setVerify(DsgApplyCus.VERIFY_NO);
                service.save(cus);
                cusInfo = cus;
            }
        } else if (ownsType == DsgApplyBill.OWNS_TYPE_COM) {
            wrapper.eq("COM_BRC_NO", idNo);
            wrapper.eq("CUS_STATUS", DsgApplyCus.CUS_STATUS_1);
            DsgApplyCom com = comService.getOne(wrapper, false);
            if (com != null) {
                com.setAppNo(appNo);
                com.setContactList(getContactList(cusId, oid));
                com.setOid(UUIDGenerator.getUUID());
                BeanKit.resetCommonField(com);
                com.setVerify(DsgApplyCom.VERIFY_NO);
                comService.save(com);
                cusInfo = com;
            }
        } else {
            return fail("ownsType不正確");
        }
        return json(MessageConstants.SSO_STATUS_SUCCESS, cusInfo);
    }

    private List<DsgApplyContact> getContactList(String cusId, String newCusId) {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("PID", cusId);
        List<DsgApplyContact> contactList = contactService.list(wrapper);
        if (CollectionUtil.isNotEmpty(contactList)) {
            contactList.forEach(e -> {
                e.setOid(UUIDGenerator.getUUID());
                e.setPid(newCusId);
                BeanKit.resetCommonField(e);
                e.setVerify(DsgApplyContact.VERIFY_NO);
            });
            contactService.saveBatch(contactList);
            return contactList;
        }
        return null;
    }
}
